home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / bsrc_p2.arc / MAILER.C < prev    next >
Encoding:
C/C++ Source or Header  |  1988-11-30  |  25.6 KB  |  968 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software <no-Inc>                   */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          No-Cost<no-tm> Software.                       */
  7. /*        \ 1011 /                                                          */
  8. /*         ------            KopyRong (K) 1987.  ALL RIGHTS REVERSED.       */
  9. /*                                                                          */
  10. /*                                                                          */
  11. /*                 This module was written by Bob Hartman                   */
  12. /*                                                                          */
  13. /*                                                                          */
  14. /*                 BinkleyTerm FTSC Mail Session Routines                   */
  15. /*                                                                          */
  16. /*                                                                          */
  17. /*                                                                          */
  18. /*   This  software  package is being distributed WITH FULL SOURCE CODE     */
  19. /*   with the  following  conditions:    1)  If  anything awful happens     */
  20. /*   because  you  use    it   (or  don't  use  it),  you  accept  full     */
  21. /*   responsibility;  2) you  don't start making tons of voice calls to     */
  22. /*   the authors to complain or  make  suggestions  about enhancements,     */
  23. /*   useful or otherwise;  3) you  do not reuse this code in commercial     */
  24. /*   products without specific permission to do so  from  the  authors;     */
  25. /*   4) If you find any problems you send  fixes  to  the  authors  for     */
  26. /*   inclusion  in  updates;    5) You find some way  to  express  your     */
  27. /*   appreciation  for  this  method of distribution, either by writing     */
  28. /*   code or  application  notes,  or  just sending along a "Thank You"     */
  29. /*   message.                                                               */
  30. /*                                                                          */
  31. /*   There is  copyrighted  code  in  this product.  We either wrote it     */
  32. /*   ourselves or got  permission  to use it.  Please don't force us to     */
  33. /*   pay a lawyer --  have some respect for our motives and don't abuse     */
  34. /*   this "license".                                                        */
  35. /*                                                                          */
  36. /*                                                                          */
  37. /*--------------------------------------------------------------------------*/
  38.  
  39. #include <stdio.h>
  40. #include <signal.h>
  41. #include <ctype.h>
  42. #include <conio.h>
  43. #include <sys/types.h>
  44. #include <sys/stat.h>
  45. #include <fcntl.h>
  46. #include <time.h>
  47. #include "com.h"
  48. #include "xfer.h"
  49. #include "keybd.h"
  50. #include "sched.h"
  51.  
  52. extern int boss_net;
  53. extern int boss_node;
  54. extern int un_attended;
  55. extern int fullscreen;
  56. extern int remote_net, remote_node;
  57. extern int redo_dynam;
  58. extern int num_events;
  59. extern int port_ptr;
  60. int called_net, called_node, mail_only;
  61. int caller;
  62. extern struct _node nodedes;            /* desc. of node             */
  63. extern int cur_event;
  64. extern EVENT *e_ptrs[];
  65. extern int got_bundle, got_arcmail, got_mail;
  66. extern int sent_mail;
  67. extern int share;
  68. extern int noforce;
  69. extern int max_connects;
  70. extern int max_noconnects;
  71. extern char *BBSreader;
  72. extern char *BOSSphone;
  73.  
  74. char BBSwelcome[1024];
  75. char *eflags="CHOFDR";
  76.  
  77. static char *outb[] = {
  78.    "*.?UT", "*.?LO", "*.REQ", NULL, (char *) (-1)
  79. };
  80.  
  81. int name_counter;
  82. int find_counter;
  83. struct FILEINFO dta_str;
  84. char next_one[64];
  85. int last_returned = -1;
  86. int last_event = -2;
  87.  
  88.  
  89. boss_mail()
  90. {
  91.    if ((!boss_net)
  92.    || (!ctl.alias[0].net)
  93.    || (!ctl.alias[0].node))
  94.        {
  95.        status_line("!Insufficient data for session");
  96.        set_xy("");
  97.        }
  98.    else
  99.        {
  100.       XON_DISABLE();
  101.       if (!CARRIER)
  102.          {
  103.          mdm_init(ctl.m_init);                /* Reinitialize the modem  */
  104.          }
  105.  
  106.        do_mail(boss_net, boss_node, 1);
  107.        }
  108. }
  109.  
  110. extern char junk[];
  111.  
  112. do_mail(bnet, bnode, manual)
  113. {
  114.    long t, timerset();
  115.  
  116.    caller = 1;
  117.    got_bundle = 0;
  118.    got_arcmail = 0;
  119.    got_mail = 0;
  120.    sent_mail = 0;
  121.    sprintf(junk,"%d/%d",bnet,bnode);
  122.    remote_net = bnet;
  123.    remote_node = bnode;
  124.    called_net = bnet;
  125.    called_node = bnode;
  126.    if (!nodeproc(junk))
  127.        return(0);
  128.  
  129.    /* Do we have a special case for the boss */
  130.    if (((called_net == boss_net) && (called_node == boss_node)) &&
  131.        (BOSSphone != NULL))
  132.       {
  133.       strcpy (nodedes.phone, BOSSphone);
  134.       }
  135.  
  136.    if (manual && CARRIER)            /* called manually maybe? */
  137.     goto process_the_damned_mail;        /* yup, just do some mail */
  138.  
  139.    if (manual)
  140.       try_2_connect(nodedes.phone);        /* try to connect         */
  141.    else
  142.       {
  143.       /* If this is supposed to be only local, then get out if it isn't */
  144.       if ((e_ptrs[cur_event]->behavior & MAT_LOCAL) && (nodedes.cost > 0))
  145.          return(0);
  146.       try_1_connect(nodedes.phone);        /* try to connect         */
  147.       }
  148.  
  149. process_the_damned_mail:
  150.  
  151.    if (CARRIER)                    /* if we did,             */
  152.       {
  153.       /* Clear out all the crap in case we had MNP stuff */
  154.       t = timerset (100);
  155.       while (!timeup (t))
  156.          time_release();
  157.       CLEAR_OUTBOUND();
  158.       CLEAR_INBOUND();
  159.  
  160.        b_session(1);            /* do a mail session      */
  161.       mdm_hangup();
  162.       return (1);
  163.       }
  164.    else
  165.       {
  166.       status_line ("+End of connection attempt");
  167.       }
  168.    return (2);
  169. }
  170.  
  171. handle_inbound_mail()
  172. {
  173. long t, timerset();            /* used for the timeouts  */
  174.  
  175.    caller = 0;
  176.  
  177. inloop:
  178.  
  179.    if (!CHAR_AVAIL())            /* Any action from modem? */
  180.       {
  181.       time_release();
  182.        return (0);                /* No, nothing to do      */
  183.       }
  184.  
  185.    /* if outbound only, then return */
  186.    if ((cur_event >= 0) && (e_ptrs[cur_event]->behavior & MAT_OUTONLY))
  187.       {
  188.       time_release();
  189.       return (0);
  190.       }
  191.  
  192.    mail_only = 1;
  193.    if ((cur_event >= 0) && (e_ptrs[cur_event]->behavior & MAT_BBS))
  194.       mail_only = 0;
  195.  
  196.    if (modem_response(100))        /* see if we got a carrier*/
  197.     {
  198.     t = timerset(200);        /* 2 seconds...           */
  199.     while (!timeup(t))
  200.       time_release();        /* wait for other side    */
  201.     }
  202. else
  203.     {
  204.     t = timerset(6000);        /* 1 minute               */
  205.     while ((!timeup(t))
  206.     &&     (!CHAR_AVAIL())
  207.     &&     (!KEYPRESS()))
  208.       time_release();        /* wait for another result*/
  209.     if (KEYPRESS())            /* If aborted by user,    */
  210.         {
  211. /*        FOSSIL_CHAR();      */    /* eat the character      */
  212.         return (1);            /* and get out,           */
  213.         }        
  214.     goto inloop;            /* else proceed along     */
  215.     }
  216.  
  217.    if (CARRIER)                /* if we have a carrier,  */
  218.       {
  219.       /* Clear out all the crap in case we had MNP stuff */
  220.       t = timerset (100);
  221.       while (!timeup (t))
  222.          time_release();
  223.       CLEAR_OUTBOUND();
  224.       CLEAR_INBOUND();
  225.  
  226.        b_session(0);        /* do a mail session      */
  227.  
  228.       /* We got inbound mail */
  229.       if (got_arcmail || got_bundle || got_mail)
  230.          {
  231.          receive_exit ();
  232.          }
  233.       }
  234.    mdm_hangup();
  235.    return (1);
  236. }
  237.  
  238. xmit_sameplace ()
  239. {
  240.    int i;
  241.  
  242.    if ((last_returned == -1) || (last_event != cur_event))
  243.       {
  244.       last_returned = -1;
  245.       return;
  246.       }
  247.  
  248.    sprintf (next_one, "%s%s", ctl.hold_area, outb[name_counter]);
  249.  
  250.    for (i = 0; i < find_counter; i++)
  251.       {
  252.       dfind (&dta_str, next_one, i);
  253.       }
  254. }
  255.  
  256. xmit_reset ()
  257. {
  258.    name_counter = 0;
  259.    find_counter = 0;
  260. }
  261.  
  262. xmit_next (net, node)
  263. int *net, *node;
  264. {
  265.    int done;
  266.    int i, j, k;
  267.  
  268.    /* If this is the first time, prime the pump */
  269.    if ((last_returned == -1) || (last_event != cur_event))
  270.       {
  271.       xmit_reset ();
  272.       last_event = cur_event;
  273.       }
  274.  
  275.    sprintf (next_one, "%s%s", ctl.hold_area, outb[name_counter]);
  276.  
  277.    done = 0;
  278.    i = name_counter;
  279.    j = find_counter;
  280.    last_returned = 0;
  281.    k = 0;
  282.  
  283.    /* Make sure we are in the same place in case we had a multi-tasker */
  284.    xmit_sameplace ();
  285.  
  286.    while (!done)
  287.       {
  288.       /* See if we have any more at this level */
  289.       if (dfind (&dta_str, next_one, j))
  290.          {
  291.          /* No more at this level, so go to next level */
  292.          if (outb[++i] == NULL)
  293.             i = 0;
  294.  
  295.          /* Start at the first entry */
  296.          j = 0;
  297.  
  298.          /* Did we go too far? */
  299.          if (outb[++k] == (char *) (-1))
  300.             {
  301.             done = 1;
  302.             }
  303.          else
  304.             {
  305.             sprintf (next_one, "%s%s", ctl.hold_area, outb[i]);
  306.             }
  307.          }
  308.       else
  309.          {
  310.          /* We found a name, is it valid for sending? */
  311.  
  312.          /* Continue on if it is a HOLD packet or flow file */
  313.          if (dta_str.name[9] == 'H')
  314.             {
  315.             ++j;
  316.             continue;
  317.             }
  318.  
  319.          if (sscanf (dta_str.name, "%04x%04x.", net, node) != 2)
  320.             {
  321.             ++j;
  322.             continue;
  323.             }
  324.  
  325.          if ((*net<0) || (*node < 0))
  326.             {
  327.             ++j;
  328.             continue;
  329.             }
  330.  
  331.          /* See if we spent too much calling him already */
  332.          if (bad_call (*net, *node, 0))
  333.             {
  334.             ++j;
  335.             continue;
  336.             }
  337.  
  338.          /* If it is a crash only event, then try next packet */
  339.          if ((dta_str.name[9] != 'C') && (e_ptrs[cur_event]->behavior & MAT_CM))
  340.             {
  341.             ++j;
  342.             continue;
  343.             }
  344.  
  345.          /* Is it a legal char for calling */
  346.          if (strchr (eflags, dta_str.name[9]) == NULL)
  347.             {
  348.             ++j;
  349.             continue;
  350.             }
  351.  
  352.          /* Is this a local only event? */
  353.          if (e_ptrs[cur_event]->behavior & MAT_LOCAL)
  354.             {
  355.             if (!nodefind(*net, *node))
  356.                {
  357.                ++j;
  358.                continue;
  359.                }
  360.             else
  361.                {
  362.                /* If this is supposed to be only local, then get out if it isn't */
  363.                if (nodedes.cost > 0)
  364.                   {
  365.                   ++j;
  366.                   continue;
  367.                   }
  368.                }
  369.             }
  370.  
  371.          last_returned = 1;
  372.          done = 1;
  373.          }
  374.       }
  375.  
  376.    /* If we got out, then we have no more to do */
  377.    name_counter = i;
  378.    find_counter = j + 1;
  379.    return (last_returned);
  380. }
  381.  
  382. static char *mon[12] = {
  383.     "Jan","Feb","Mar","Apr","May","Jun",
  384.     "Jul","Aug","Sep","Oct","Nov","Dec"
  385.     };
  386.  
  387. unattended ()
  388. {
  389.    int bnet, bnode;
  390.    int i, j, k, l, m, r;
  391.    int more_mail;
  392.    long init_timer, t, timerset(), random_time();            /* used for the timeouts  */
  393.    int done = 1;        /* if we exit with this, get out of BT */
  394.    FILE *tfile;
  395.    char jbuf[21];
  396.    struct tm *tp;
  397.    time_t ltime;
  398.  
  399.    un_attended = 1;
  400.  
  401.    if (fullscreen)
  402.       {
  403.       opening_banner ();
  404.       mailer_banner ();
  405.       }
  406.  
  407.    if ((tfile = fopen ("BINKLEY.BAN", "rb")) != NULL)
  408.       {
  409.       fread (BBSwelcome, 1, 1000, tfile);
  410.       fclose (tfile);
  411.       }
  412.    else
  413.       {
  414.       BBSwelcome [0] = '\0';
  415.       }
  416.  
  417.    /* Initialize the random number generator */
  418.    i = (int) time (NULL);
  419.    srand (i);
  420.  
  421.    status_line ("+begin, %s", xfer_id);
  422.    set_xy ("");
  423.    XON_DISABLE();
  424.  
  425.    /* Turn off forced events */
  426.    if (noforce)
  427.       {
  428.       find_event ();
  429.       noforce = 0;
  430.       }
  431.    if (redo_dynam)
  432.       {
  433.       for (i = 0; i < num_events; i++)
  434.          {
  435.          e_ptrs[i]->behavior &= ~MAT_SKIP;
  436.          }
  437.       redo_dynam = 0;
  438.       }
  439.  
  440.    /* See if we should exit before initializing the modem
  441.       (and therefore possibly letting a call sneak through */
  442.    find_event ();
  443.  
  444.    if (!CARRIER)
  445.       {
  446.       mdm_init(ctl.m_init);                /* Reinitialize the modem  */
  447.       }
  448.  
  449.    init_timer = timerset (60000);   /* Set a 10 minute timer */
  450.  
  451. mail_top:
  452.    un_attended = 1;
  453.    i = 0;
  454.    m = 1;
  455.  
  456.    /* As long as we don't press a key */
  457.    l = 0;
  458.    r = 0;
  459.    more_mail = 1;
  460. esc_only:
  461.    while (!KEYPRESS())
  462.       {
  463.       find_event ();
  464.  
  465.       /* Show that we are ready */
  466.       if (m)
  467.          {
  468.          if (fullscreen)
  469.             {
  470.             clear_filetransfer();
  471.             clear_bottom();
  472.             gotoxy (69, 7);
  473.             cprintf ("%-2d Ready  ", cur_event + 1);
  474.             }
  475.          else
  476.             {
  477.             status_line (" Event %d - Ready", cur_event + 1);
  478.             }
  479.          init_timer = timerset (60000);   /* Set a 10 minute timer */
  480.          }
  481.  
  482.       /* If we haven't gotten anything in 10 minutes, re-init the modem */
  483.       if (timeup (init_timer))
  484.          {
  485.          mdm_init (ctl.m_init);
  486.          init_timer = timerset (60000);   /* Set a 10 minute timer */
  487.  
  488.          if (fullscreen)
  489.             {
  490.             time(<ime);
  491.             tp = localtime(<ime);
  492.             gotoxy (69,8);
  493.             cprintf ("%02i:%02i:%02i", tp->tm_hour, tp->tm_min, tp->tm_sec);
  494.             gotoxy (69,9);
  495.             cprintf ("%02i %03s %02i", tp->tm_mday, mon[tp->tm_mon], tp->tm_year);
  496.             }
  497.  
  498.          /* Say that we have more mail so that things entered through other
  499.             side of a multi-tasker will still go out */
  500.          if (!more_mail)
  501.             {
  502.             xmit_reset ();
  503.             more_mail = 1;
  504.             }
  505.          }
  506.  
  507.       m = 0;
  508.  
  509.       if ((cur_event >= 0) && (!(e_ptrs[cur_event]->behavior & MAT_OUTONLY)))
  510.          {
  511.          /* set up the amount of time to wait at random */
  512.          t = random_time (e_ptrs[cur_event]->wait_time);
  513.  
  514.          while ((!timeup(t)) && (!KEYPRESS()) && (m == 0))
  515.             {
  516.             find_event ();
  517.  
  518.             time_release ();
  519.  
  520.             /* See if we need to handle inbound mail   */
  521.             if (m = handle_inbound_mail())
  522.                {
  523.                /* If we sent out anything, make sure we reset stuff */
  524.                xmit_sameplace ();
  525.                }
  526.             }
  527.  
  528.          if (m)
  529.             {
  530.             clear_filetransfer();
  531.             clear_bottom();
  532.             gotoxy (69, 7);
  533.             cprintf ("%-2d Ready  ", cur_event + 1);
  534.             }
  535.  
  536.          l = 0;
  537.          }
  538.  
  539. immed_call:
  540.       find_event ();
  541.  
  542.       /* If we are not in an event, loop again */
  543.       if (cur_event < 0)
  544.          {
  545.          time_release ();
  546.          continue;
  547.          }
  548.  
  549.       /* If we have pressed a key, get out */
  550.       if (KEYPRESS())
  551.          break;
  552.  
  553.       /* See if we are supposed to do any mail */
  554.       if (e_ptrs[cur_event]->behavior & MAT_NOOUT)
  555.          {
  556.          continue;
  557.          }
  558.  
  559.       if (more_mail)
  560.          {
  561.          if (more_mail = xmit_next (&bnet, &bnode))
  562.             {
  563.             m = do_mail (bnet, bnode,0);
  564.  
  565.             r = (m == 1)?1:0;
  566.  
  567.             if (r && !sent_mail)
  568.                {
  569.                bad_call (bnet, bnode, 1);
  570.                }
  571.             else if (r)
  572.                {
  573.                /* We got through, so delete his status file */
  574.                bad_call (bnet, bnode, -1);
  575.                }
  576.             else if (m == 2)
  577.                {
  578.                bad_call (bnet, bnode, 2);
  579.                }
  580.  
  581.             /* If we did some processing */
  582.             if (m)
  583.                {
  584.                /* We got inbound mail */
  585.                if (got_arcmail || got_bundle || got_mail)
  586.                   {
  587.                   receive_exit ();
  588.                   }
  589.                }
  590.             }
  591.          }
  592.  
  593.       if (!more_mail)
  594.          {
  595.          /* No more mail to do, was it dynamic? */
  596.          if (e_ptrs[cur_event]->behavior & MAT_DYNAM)
  597.             {
  598.             e_ptrs[cur_event]->behavior |= MAT_SKIP;
  599.             status_line (":End of Dynamic Event %d", cur_event + 1);
  600.             set_xy ("");
  601.             m = 1;
  602.             }
  603.          }
  604.       }
  605.  
  606.    /* Eat the character we pressed */
  607.     if (!KEYPRESS())
  608.       {
  609.       /* Be serious, there had to be a key pressed or we wouldn't be here */
  610.       /* I know it sounds silly, but ^C will sometimes do crap like this  */
  611.       status_line (":Exit requested from keyboard");
  612.       }
  613.    else
  614.       {
  615.       i = FOSSIL_CHAR();
  616.       if ((i & 0xff) == 0)
  617.          {
  618.          switch (i)
  619.             {
  620.             case PF1:
  621.             case PF2:
  622.             case PF3:
  623.             case PF4:
  624.             case PF5:
  625.             case PF6:
  626.             case PF7:
  627.             case PF8:
  628.             case PF9:
  629.             case PF10:
  630.                i = i >> 8;
  631.                status_line (":Function key exit - errorlevel %d", (i - 0x3a) * 10);
  632.                errl_exit ((i - 0x3a) * 10);
  633.  
  634.             case ALTE:
  635.                if (BBSreader != NULL)
  636.                   {
  637.                   status_line (" Disabling Modem");
  638.                   mdm_init (ctl.m_busy);
  639.                   DTR_OFF();
  640.                   status_line (":Invoking Message Reader");
  641.                   system (BBSreader);
  642.                   if (fullscreen)
  643.                      {
  644.                      opening_banner ();
  645.                      mailer_banner ();
  646.                      }
  647.                   status_line (":Message Reader returned to BinkleyTerm");
  648.                   status_line (" Enabling Modem");
  649.                   DTR_ON();
  650.                   mdm_init (ctl.m_init);
  651.                   m = 1;
  652.                   l = 0;
  653.                   goto immed_call;
  654.                   }
  655.                else
  656.                   {
  657.                   set_xy (NULL);
  658.                   status_line ("!No Message Reader to invoke");
  659.                   set_xy (NULL);
  660.                   m = 1;
  661.                   goto esc_only;
  662.                   }
  663.  
  664.             case ALTM:
  665.                status_line (":Entering POLL Mode");
  666.                gotoxy (0,22);
  667.                un_attended = 0;
  668.                scr_printf ("\r\nPlease enter a net/node number: ");
  669.                fgets (jbuf, 20, stdin);
  670.                jbuf[strlen(jbuf)-1] = '\0';
  671.                if (sscanf (jbuf, "%d/%d", &bnet, &bnode) == 2)
  672.                   {
  673.                   do_mail (bnet, bnode, 1);
  674.                   }
  675.                un_attended = 1;
  676.                if (fullscreen)
  677.                   {
  678.                   opening_banner ();
  679.                   mailer_banner ();
  680.                   }
  681.                status_line (":Poll completed");
  682.                DTR_ON();
  683.                mdm_init (ctl.m_init);
  684.                m = 1;
  685.                l = 0;
  686.                goto immed_call;
  687.                
  688.             case ALTR:
  689.                for (j = 0; j < num_events; j++)
  690.                   {
  691.                   /* Don't redo forced events */
  692.                   if (!(e_ptrs[j]->behavior & MAT_FORCED))
  693.                      {
  694.                      e_ptrs[j]->behavior &= ~MAT_SKIP;
  695.                      }
  696.                   }
  697.                goto mail_top;
  698.  
  699.             case ALTQ:
  700.                e_ptrs[cur_event]->behavior |= MAT_SKIP;
  701.                goto mail_top;
  702.  
  703.             case ALTT:
  704.                status_line (":Keyboard request to enter terminal mode");
  705.                done = 0;        /* We won't exit now */
  706.                goto mail_done;
  707.  
  708.             case ALTF10:
  709.                mailer_help();
  710.                if (fullscreen)
  711.                   {
  712.                   opening_banner ();
  713.                   mailer_banner();
  714.                   }
  715.                m = 1;
  716.                goto esc_only;
  717.  
  718.             case ALTX:
  719.                status_line (":Exit requested from keyboard");
  720.                goto mail_done;
  721.  
  722.             default:
  723.                status_line (" Junk character from keyboard - continuing");
  724.                m = 1;
  725.                goto esc_only;
  726.             }
  727.          }
  728.       else
  729.          {
  730.          switch (i & 0xff)
  731.             {
  732.             case 'C':
  733.             case 'c':
  734.                status_line (" Immediate call requested");
  735.                m = 0;
  736.                l = 0;
  737.                more_mail = 1;
  738.                goto immed_call;
  739.  
  740.             case 3:
  741.                status_line (":Exit requested from keyboard");
  742.                goto mail_done;
  743.  
  744.             case ESC:
  745.                status_line (":Exiting to DOS");
  746.                gotoxy (0,22);
  747.                cputs ("Type EXIT to return to BT");
  748.                DTR_OFF();
  749.                system ("COMMAND.COM");
  750.                if (fullscreen)
  751.                   {
  752.                   opening_banner ();
  753.                   mailer_banner ();
  754.                   }
  755.                DTR_ON();
  756.                status_line (":BinkleyTerm Reactivated");
  757.                m = 1;
  758.                goto esc_only;
  759.  
  760.             default:
  761.                status_line (" Junk character from keyboard - continuing");
  762.                m = 1;
  763.                goto esc_only;
  764.             }
  765.          }
  766.       }
  767.  
  768. mail_done:
  769.    status_line ("+end, %s", xfer_id);
  770.    un_attended = 0;
  771.    gotoxy (0,22);
  772.    XON_ENABLE();
  773.    return(done);
  774. }
  775.  
  776. receive_exit ()
  777. {
  778.    if (got_arcmail && (cur_event >= 0) && (e_ptrs[cur_event]->errlevel[2]))
  779.       {
  780.       status_line(":Exit after ARCmail with errorlevel %d",
  781.                     e_ptrs[cur_event]->errlevel[2]);
  782.  
  783.       errl_exit (e_ptrs[cur_event]->errlevel[2]);
  784.       }
  785.  
  786.    if ((got_mail || got_bundle) &&
  787.       (cur_event >= 0) && (e_ptrs[cur_event]->errlevel[1]))
  788.       {
  789.       status_line(":Exit after receiving mail with errorlevel %d",
  790.                     e_ptrs[cur_event]->errlevel[1]);
  791.  
  792.       errl_exit (e_ptrs[cur_event]->errlevel[1]);
  793.       }
  794.  
  795.    got_arcmail = 0;
  796.    got_bundle = 0;
  797.    got_mail = 0;
  798. }
  799.  
  800. errl_exit (n)
  801. int n;
  802. {
  803.    status_line ("+end, %s", xfer_id);
  804.    mdm_init(ctl.m_busy);                /* Reinitialize the modem  */
  805.    DTR_OFF();                /* Drop DTR to avoid calls */
  806.    gotoxy (0,22);
  807. if (!share)
  808.     MDM_DISABLE();
  809.    exit (n);
  810. }
  811.  
  812. long random_time (x)
  813. int x;
  814. {
  815.    int i;
  816.    long timerset();
  817.  
  818.    if (x == 0)
  819.       {
  820.       return (0L);
  821.       }
  822.  
  823.    /* Number of seconds to delay is random based on x +/- 50% */
  824.    i = (rand () % (x + 1)) + (x / 2);
  825.  
  826.    return (timerset (i * 100));
  827. }
  828.  
  829. char fname[80];
  830. char fname1[80];
  831.  
  832. bad_call (bnet, bnode, rwd)
  833. int bnet;
  834. int bnode;
  835. int rwd;
  836. {
  837.    struct stat buffer;
  838.    char *c;
  839.    int res;
  840.    int i;
  841.  
  842.    res = -1;
  843.    sprintf (fname, "%s%04x%04x.$$", ctl.hold_area, bnet, bnode);
  844.    c = fname + strlen (fname);
  845.    *(c+1) = '\0';
  846.    for (i = 0; i <= 9; i++)
  847.       {
  848.       *c = i + '0';
  849.  
  850.       /* See if we find this name out there */
  851.       if (!stat (fname, &buffer))
  852.          {
  853.          res = i;
  854.          break;
  855.          }
  856.       }
  857.  
  858.    if (res == -1)
  859.       {
  860.       *c = '0';
  861.       }
  862.    else
  863.       {
  864.       *c = res + '0';
  865.       }
  866.  
  867.    if (rwd > 0)
  868.       {
  869.       /* We are writing out a bad call */
  870.       sprintf (fname1, "%s%04x%04x.$$%d", ctl.hold_area, bnet, bnode,
  871.          (res + 1 > 9) ? 9 : res + 1);
  872.  
  873.       if (res == -1)
  874.          {
  875.          res = open(fname1,O_CREAT+O_WRONLY+O_BINARY,S_IWRITE);
  876.          i = rwd - 1;
  877.          write (res, &i, sizeof (int));
  878.             close (res);
  879.          }
  880.       else
  881.          {
  882.          if (rwd == 2)
  883.             {
  884.             /* We had an unsuccesful no carrier attempt */
  885.             i = open(fname,O_RDONLY+O_BINARY);
  886.             read (i, &res, sizeof (int));
  887.                close (i);
  888.             ++res;
  889.             i = open(fname,O_CREAT+O_WRONLY+O_BINARY,S_IWRITE);
  890.             write (i, &res, sizeof (int));
  891.                close (i);
  892.             }
  893.          else
  894.             {
  895.             /* We had an unsuccessful attempt with carrier */
  896.             rename (fname, fname1);
  897.             }
  898.          }
  899.       }
  900.    else if (rwd == 0)
  901.       {
  902.       /* We are reading a bad call status */
  903.  
  904.       /* Is it automatically ok (no .$$ file there) ? */
  905.       if (res == -1)
  906.          return (0);
  907.  
  908.       /* Were there too many connects with carrier? */
  909.       if (res >= max_connects)
  910.          return (1);
  911.  
  912.       /* Ok, check for connects without carrier */
  913.       res = 0;
  914.       i = open (fname, O_RDONLY+O_BINARY);
  915.       read (i, &res, sizeof (int));
  916.       close (i);
  917.       return (res >= max_noconnects);
  918.       }
  919.    else
  920.       {
  921.       if (res != -1)
  922.          {
  923.          unlink (fname);
  924.          }
  925.       }
  926. }
  927.  
  928. mailer_banner ()
  929. {
  930.    int k;
  931.  
  932.    cputs ("--------------------------------------------------------------------------------");
  933.    gotoxy (0, 6);
  934.    cprintf ("                                                            | %d:%d/%d.%d\r\n",
  935.       ctl.our_zone, boss_net, boss_node,
  936.       (boss_net == ctl.alias[0].net) ? 0 : ctl.alias[0].node);
  937.    cprintf ("                                                            | Event: %-3d\r\n", cur_event + 1);
  938.    cputs ("                                                            | Time :\r\n");
  939.    cputs ("                                                            | Date :\r\n");
  940.    cprintf ("                                                            | Comm Port: %d\r\n", port_ptr+1);
  941.    cputs ("                                                            | Baud Rate:\r\n");
  942.    cputs ("--------------------------------------------------------------------------------");
  943.    gotoxy (0, 15);
  944.    cputs ("--------------------------------------------------------------------------------");
  945.    fill_in_status();
  946.    clear_filetransfer();
  947.    clear_bottom();
  948.    set_baud (ctl.max_baud, 0);
  949. }
  950.  
  951. clear_filetransfer()
  952. {
  953.    gotoxy(0,13);
  954.    cprintf ("\033[K\r\n");
  955.    cprintf ("\033[K");
  956. }
  957.  
  958. clear_bottom ()
  959. {
  960.    int i;
  961.  
  962.    gotoxy (0, 16);
  963.    for (i = 16; i <= 20; i++)
  964.       {
  965.       cprintf ("\033[K\r\n");
  966.       }
  967. }
  968.